package TrainingData;

import java.util.Iterator;
import java.util.Vector;


/**
 * @author Robert Pethes & Gergely Neu
 * 
 * Class for treating collections of TrainingInstances.
 */
public class TrainingInstanceCollection implements java.lang.Iterable<TrainingInstance>{
	
	protected Vector<TrainingInstance> _instanceArray = new Vector<TrainingInstance>();
	
	protected int _numStates = 0;
	protected int _numEmissions = 0;
	
	/**
	 * Initializes a collection.
	 * 
	 * @param numStates the number of distinct states that can be found in the instances to be included in the collection.
	 * @param numEmissions the number of distinct emissions that can be found in the instances to be included in the collection.
	 * @param instanceArray the instances to be included in the collection.
	 */
	public TrainingInstanceCollection(int numStates, int numEmissions,Vector<TrainingInstance> instanceArray){
		_numStates = numStates;
		_numEmissions = numEmissions;
		_instanceArray = instanceArray;
	}
	
	/**
	 * @return the number of instances in the collection.
	 */
	public int getSize() {
		return _instanceArray.size();
	}
	
	/**
	 * @param instance the instance to be added to the collection.
	 */
	public void add(TrainingInstance instance){
		_instanceArray.add(instance);
	}
	
	/**
	 * @param pos the index of the instance to be returned.
	 * @return the instance.
	 */
	public TrainingInstance getAt(int pos){
		return (TrainingInstance) _instanceArray.get(pos);
	}
	
	/**
	 * Splits the collection into two parts: a part that will be used for training and a part that will be used for testing.
	 * Returns the two parts as parameters. E.g., if one wants to use the last 20% of the collection for testing, testRangeBegin
	 * needs to be set to 0.8 and testRangeEnd to 1.
	 * 
	 * @param testRangeBegin the index of the first sentence to be included in the test data divided by the total size of the original collection.
	 * i.e., this parameter needs to be between 0 and 1. 
	 * @param testRangeEnd the index of the last sentence to be included in the test data divided by the total size of the original collection.
	 * i.e., this parameter needs to be between 0 and 1.
	 * @param trainingData the collection of instances used for training.
	 * @param testData the collection of instances used for testing.
	 */
	public void split(double testRangeBegin, double testRangeEnd, TrainingInstanceCollection trainingData,TrainingInstanceCollection testData) {
		int numInstances = _instanceArray.size();
		int beginIndex = (int)(testRangeBegin * numInstances);
		int endIndex = (int)(testRangeEnd * numInstances);
		
		for (int i = 0; i<numInstances; i++) {
			if (i < beginIndex || i>= endIndex)
				trainingData.add(_instanceArray.get(i));
			else
				testData.add(_instanceArray.get(i));
		}
		return;
	}

	public Iterator<TrainingInstance> iterator() {
		return _instanceArray.iterator();
	}
	
	/**
	 * @return the number of distinct states that can be found in the instances to be included in the collection.
	 */
	public int getNumStates(){
		return _numStates;
	}
	
	/**
	 * @return the number of distinct emissions that can be found in the instances to be included in the collection.
	 */
	public int getNumEmissions(){
		return _numEmissions;
	}
	
	
}	
